<?php
defined('__JF')
		or die('Direct access is not allowed');

include_once 'JF_CoreException.php';
include_once 'JF_IOException.php';
include_once 'JF_URI.php';
include_once 'JF_URIParamUtil.php';
include_once '../reflection/JF_ReflectionUtil.php';
include_once '../mvc/controller/JF_IController.php';

final class JF_RequestDispatcher {

	private $aRouteCfg;

	private $isRequest;

	private $sURI;

	private $sController;

	private $aParameters = array();

	private $aURIParamenters;

	public function __construct(array $aRouteCfg, $sQueryString, array $aPost, $s404Controller) {
		$this->aRouteCfg 		= $aRouteCfg;
		$this->sURI				= $sQueryString;
		$this->isRequest 		= !empty($aPost);
		$this->aPostParameters	= $aPost;
		$this->sController		= $s404Controller;
		$this->aURIParameters 	= array();
	}

	public function matchURI() {
		$oURI 		= new JF_URI($this->sURI);
		$isMatched	= false;
		// mapped
		for ($i = 0; $i < count($this->aRouteCfg); $i++) {
			if ($oURI->match($this->aRouteCfg[$i]['uri'])) {
				if (array_key_exists('component', $this->aRouteCfg[$i])) {
					$this->sController 		= 'component/' . $this->aRouteCfg[$i]['component'];
				}
				else {
					$this->sController 		= 'library/jiko/mvc';
				}

				$this->sController		.= '/controller/' . $this->aRouteCfg[$i]['controller']. 'Controller.php';
				$this->aParameters		= $this->aRouteCfg[$i]['parameters'];
				$this->aURIParameters	= $oURI->getMatched();
				$isMatched				= true;
				break;
			}

		}

		// direct
		if (!$isMatched && preg_match('/^[a-z0-9\/_\.]+$/i', $this->sURI)) {
			$aController 	= explode('/', $this->sURI);
			$iCount			= count($aController);
			$sPattern		= '/^[a-z0-9_]+$/i';
			if (($iCount > 1) && (preg_match($sPattern, $aController[0])) && (preg_match($sPattern, $aController[1]))) {
				$sController = 'component/' . strtolower($aController[0]) . '/controller/' . ucfirst($aController[1]). 'DirectController.php';
				if (JF_FileUtil::exists($sController)) {
					$this->aParameters['404Controller']	= $this->sController;
					$this->sController 					= $sController;
					$this->aParameters['method']		= 'view';
					if (($iCount > 2) && (preg_match($sPattern, $aController[2]))) {
						$this->aParameters['method'] = $aController[2];
						if ($iCount > 3) {
							$this->aParameters['arguments'] = array();
							for ($i = 3; $i < $iCount; $i++) {
								$this->aParameters['arguments'][] = JF_URIParamUtil::detectValue($aController[$i]);
							}

						}

					}

				}

			}

		}

	}

	public function execute() {
		$oController = JF_ReflectionUtil::newInstance($this->sController, array(), 'JF_IController');
		$oController->isRequest($this->isRequest);
		$oController->setURI($this->sURI);
		$oController->setURIParameters($this->aURIParameters);
		$oController->setParameters($this->aParameters);
		$oController->setPostParameters($this->aPostParameters);
		$oController->execute();
	}



}